﻿namespace Fiddler
{
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.IO;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading;
    using System.Windows.Forms;
    using System.Xml;

    public class AutoResponder
    {
        private List<ResponderRule> _alRules = new List<ResponderRule>();
        private bool _bEnabled;
        private bool _bPermitFallthrough;
        private bool _bRuleListIsDirty;
        private bool _bUseLatency;
        private ReaderWriterLock _RWLockRules = new ReaderWriterLock();
        private UIAutoResponder oAutoResponderUI = new UIAutoResponder();

        internal AutoResponder()
        {
        }

        internal void AddActionToUI(string sAction)
        {
            this.oAutoResponderUI.cbxRuleAction.Items.Add(sAction);
        }

        public ResponderRule AddRule(string sRule, string sAction, bool bIsEnabled)
        {
            return this.AddRule(sRule, null, null, sAction, 0, bIsEnabled);
        }

        public ResponderRule AddRule(string sRule, Session oImportedSession, string sDescription, bool bEnabled)
        {
            if (oImportedSession != null)
            {
                return this.AddRule(sRule, oImportedSession.oResponse.headers, oImportedSession.responseBodyBytes, sDescription, 0, bEnabled);
            }
            return this.AddRule(sRule, null, null, sDescription, 0, bEnabled);
        }

        public ResponderRule AddRule(string sRule, Session oImportedSession, string sDescription, int iLatencyMS, bool bEnabled)
        {
            return this.AddRule(sRule, oImportedSession.oResponse.headers, oImportedSession.responseBodyBytes, sDescription, iLatencyMS, bEnabled);
        }

        public ResponderRule AddRule(string sRule, HTTPResponseHeaders oRH, byte[] arrResponseBody, string sDescription, int iLatencyMS, bool bEnabled)
        {
            try
            {
                ResponderRule item = new ResponderRule(sRule, oRH, arrResponseBody, sDescription, iLatencyMS, bEnabled);
                try
                {
                    this.GetWriterLock();
                    this._alRules.Add(item);
                }
                finally
                {
                    this.FreeWriterLock();
                }
                this._bRuleListIsDirty = true;
                this.CreateViewItem(item);
                return item;
            }
            catch (Exception)
            {
                return null;
            }
        }

        internal void AddToUI()
        {
            FiddlerApplication.UI.pageResponder.Controls.Add(this.oAutoResponderUI);
            this.oAutoResponderUI.Parent = FiddlerApplication.UI.pageResponder;
            this.oAutoResponderUI.Dock = DockStyle.Fill;
        }

        private bool CheckMatch(Session oS, ResponderRule oCandidate)
        {
            if (!oCandidate.IsEnabled)
            {
                return false;
            }
            string sMatch = oCandidate.sMatch;
            return CheckMatch(oS.fullUrl, oS, oCandidate.sMatch);
        }

        internal static bool CheckMatch(string sURI, Session oSession, string sLookFor)
        {
            string sBodyToMatch = null;
            if (sLookFor.StartsWith("METHOD:", StringComparison.OrdinalIgnoreCase))
            {
                sLookFor = sLookFor.Substring(7);
                string sTestFor = Utilities.TrimAfter(sLookFor, ' ');
                if (!oSession.HTTPMethodIs(sTestFor))
                {
                    return false;
                }
                sLookFor = sLookFor.Contains(" ") ? Utilities.TrimBefore(sLookFor, ' ') : "*";
            }
            if (sLookFor.StartsWith("URLWithBody:", StringComparison.OrdinalIgnoreCase))
            {
                sLookFor = sLookFor.Substring(12);
                sBodyToMatch = Utilities.TrimBefore(sLookFor, ' ');
                sLookFor = Utilities.TrimAfter(sLookFor, ' ');
            }
            if (sLookFor.StartsWith("HEADER:", StringComparison.OrdinalIgnoreCase))
            {
                sLookFor = sLookFor.Substring(7);
                if (sLookFor.Contains("="))
                {
                    string sHeaderName = Utilities.TrimAfter(sLookFor, "=");
                    string sHeaderValue = Utilities.TrimBefore(sLookFor, "=");
                    return oSession.oRequest.headers.ExistsAndContains(sHeaderName, sHeaderValue);
                }
                return oSession.oRequest.headers.Exists(sLookFor);
            }
            if (sLookFor.StartsWith("FLAG:", StringComparison.OrdinalIgnoreCase))
            {
                sLookFor = sLookFor.Substring(5);
                if (!sLookFor.Contains("="))
                {
                    return oSession.oFlags.ContainsKey(sLookFor);
                }
                string str5 = Utilities.TrimAfter(sLookFor, "=");
                string str6 = Utilities.TrimBefore(sLookFor, "=");
                string str7 = oSession.oFlags[str5];
                if (str7 == null)
                {
                    return false;
                }
                return (str7.IndexOf(str6, StringComparison.OrdinalIgnoreCase) > -1);
            }
            if ((sLookFor.Length > 6) && sLookFor.StartsWith("REGEX:", StringComparison.OrdinalIgnoreCase))
            {
                bool flag=false;
                string pattern = sLookFor.Substring(6);
                try
                {
                    Regex regex = new Regex(pattern);
                    if (!regex.Match(sURI).Success)
                    {
                        return false;
                    }
                    if (!IsBodyMatch(oSession, sBodyToMatch))
                    {
                        return false;
                    }
                    flag = true;
                }
                catch
                {
                }
                return flag;
            }
            if ((sLookFor.Length > 6) && sLookFor.StartsWith("EXACT:", StringComparison.OrdinalIgnoreCase))
            {
                if (!sLookFor.Substring(6).Equals(sURI, StringComparison.Ordinal))
                {
                    return false;
                }
                if (!IsBodyMatch(oSession, sBodyToMatch))
                {
                    return false;
                }
                return true;
            }
            if ((sLookFor.Length > 4) && sLookFor.StartsWith("NOT:", StringComparison.OrdinalIgnoreCase))
            {
                string str10 = sLookFor.Substring(4);
                if (sURI.IndexOf(str10, StringComparison.OrdinalIgnoreCase) >= 0)
                {
                    return false;
                }
                if (!IsBodyMatch(oSession, sBodyToMatch))
                {
                    return false;
                }
                return true;
            }
            if (sLookFor == "*")
            {
                if (!IsBodyMatch(oSession, sBodyToMatch))
                {
                    return false;
                }
                return true;
            }
            if (-1 >= sURI.IndexOf(sLookFor, StringComparison.OrdinalIgnoreCase))
            {
                return false;
            }
            if (!IsBodyMatch(oSession, sBodyToMatch))
            {
                return false;
            }
            return true;
        }

        internal void ClearActionsFromUI()
        {
            this.oAutoResponderUI.cbxRuleAction.Items.Clear();
        }

        public void ClearRules()
        {
            try
            {
                this.GetWriterLock();
                this._alRules.Clear();
            }
            finally
            {
                this.FreeWriterLock();
            }
            FiddlerApplication.UIInvoke(delegate
            {
                this.oAutoResponderUI.lvRespondRules.Items.Clear();
            });
            this._bRuleListIsDirty = true;
        }

        internal bool CreateRuleForFile(string sFilename, string sRelativeTo)
        {
            if ((sFilename == null) || !File.Exists(sFilename))
            {
                return false;
            }
            try
            {
                string fileName = null;
                if (string.IsNullOrEmpty(sRelativeTo))
                {
                    fileName = Path.GetFileName(sFilename);
                }
                else
                {
                    fileName = sFilename.Substring(sRelativeTo.Length).Replace('\\', '/');
                }
                fileName = Utilities.UrlPathEncode(fileName);
                bool flag = (((fileName.EndsWith(".htm", StringComparison.OrdinalIgnoreCase) || fileName.EndsWith(".html", StringComparison.OrdinalIgnoreCase)) || (fileName.EndsWith(".php", StringComparison.OrdinalIgnoreCase) || fileName.EndsWith(".cgi", StringComparison.OrdinalIgnoreCase))) || (fileName.EndsWith(".asp", StringComparison.OrdinalIgnoreCase) || fileName.EndsWith(".cfm", StringComparison.OrdinalIgnoreCase))) || fileName.EndsWith(".aspx", StringComparison.OrdinalIgnoreCase);
                string sRule = "REGEX:(?insx).*" + Utilities.RegExEscape(fileName, false, !flag);
                if (flag)
                {
                    sRule = sRule + @"(\?.*)?$";
                }
                string sAction = sFilename;
                this.AddRule(sRule, sAction, true);
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        internal void CreateRulesForFolder(string sFolderName)
        {
            DirectoryInfo info = new DirectoryInfo(sFolderName);
            foreach (FileInfo info2 in info.GetFiles("*", SearchOption.AllDirectories))
            {
                this.CreateRuleForFile(info2.FullName, info.Parent.FullName);
            }
        }

        private void CreateViewItem(ResponderRule oRule)
        {
            if (oRule != null)
            {
                ListViewItem item = this.oAutoResponderUI.lvRespondRules.Items.Add(oRule.sMatch);
                oRule.ViewItem = item;
                item.SubItems.Add(oRule.sAction);
                item.SubItems.Add(oRule.iLatency.ToString());
                item.Tag = oRule;
                item.Checked = oRule.IsEnabled;
                if (!item.Checked)
                {
                    item.ForeColor = Color.FromKnownColor(KnownColor.ControlDark);
                }
            }
        }

        internal bool DemoteRule(ResponderRule oRule)
        {
            bool flag;
            try
            {
                this.GetWriterLock();
                int index = this._alRules.IndexOf(oRule);
                if ((index > -1) && (index < (this._alRules.Count - 1)))
                {
                    this._alRules.Reverse(index, 2);
                    this._bRuleListIsDirty = true;
                    return true;
                }
                flag = false;
            }
            finally
            {
                this.FreeWriterLock();
            }
            return flag;
        }

        private static void DoDelay(ResponderRule oMatch)
        {
            if (FiddlerApplication.oAutoResponder.UseLatency && (oMatch.iLatency > 0))
            {
                Thread.Sleep(oMatch.iLatency);
            }
        }

        internal void DoMatchAfterRequestTampering(Session oSession)
        {
            try
            {
                this.GetReaderLock();
                using (List<ResponderRule>.Enumerator enumerator = this._alRules.GetEnumerator())
                {
                    MethodInvoker oDel = null;
                    ResponderRule oCandidate;
                    while (enumerator.MoveNext())
                    {
                        oCandidate = enumerator.Current;
                        if ((!string.IsNullOrEmpty(oCandidate.sAction) && !oCandidate.sAction.Equals("*bpu", StringComparison.OrdinalIgnoreCase)) && this.CheckMatch(oSession, oCandidate))
                        {
                            bool flag = HandleMatch(oSession, oCandidate);
                            if (oCandidate.bDisableOnMatch)
                            {
                                oCandidate.IsEnabled = false;
                                if (oDel == null)
                                {
                                    oDel = delegate
                                    {
                                        oCandidate.ViewItem.Checked = false;
                                    };
                                }
                                FiddlerApplication.UIInvokeAsync(oDel, null);
                            }
                            if (flag)
                            {
                                return;
                            }
                        }
                    }
                }
            }
            finally
            {
                this.FreeReaderLock();
            }
            if (!this._bPermitFallthrough)
            {
                oSession["ui-backcolor"] = "Lavender";
                oSession.SetBitFlag(SessionFlags.ResponseGeneratedByFiddler, true);
                if (!oSession.HTTPMethodIs("CONNECT"))
                {
                    if (oSession.state < SessionStates.SendingRequest)
                    {
                        oSession.utilCreateResponseAndBypassServer();
                    }
                    else
                    {
                        oSession.bBufferResponse = true;
                        oSession.responseBodyBytes = new byte[0];
                    }
                    oSession.state = SessionStates.ReadingResponse;
                    oSession.oResponse["Date"] = DateTime.Now.ToUniversalTime().ToString("r");
                    if (oSession.oRequest.headers.Exists("If-Modified-Since") || oSession.oRequest.headers.Exists("If-None-Match"))
                    {
                        oSession.responseCode = 0x130;
                    }
                    else
                    {
                        oSession.responseCode = 0x194;
                        oSession.oResponse["Cache-Control"] = "max-age=0, must-revalidate";
                        if (!oSession.HTTPMethodIs("HEAD"))
                        {
                            oSession.utilSetResponseBody("[Fiddler] The Fiddler AutoResponder is enabled, but this request did not match any of the listed rules. Because the \"Unmatched requests passthrough\" option on the AutoResponder tab is not enabled, this HTTP/404 response has been generated.".PadRight(0x200, ' '));
                        }
                    }
                }
                else
                {
                    oSession.oFlags["x-replywithtunnel"] = "AutoResponderWithNoFallthrough";
                }
            }
        }

        internal void DoMatchBeforeRequestTampering(Session oSession)
        {
            try
            {
                this.GetReaderLock();
                foreach (ResponderRule rule in this._alRules)
                {
                    if (rule.sAction.Equals("*bpu", StringComparison.OrdinalIgnoreCase) && this.CheckMatch(oSession, rule))
                    {
                        oSession["x-breakrequest"] = "AutoResponder";
                        return;
                    }
                }
            }
            finally
            {
                this.FreeReaderLock();
            }
        }

        internal bool ExportFARX(string sFilename)
        {
            return this.SaveRules(sFilename);
        }

        private void FreeReaderLock()
        {
            this._RWLockRules.ReleaseReaderLock();
        }

        private void FreeWriterLock()
        {
            this._RWLockRules.ReleaseWriterLock();
        }

        private void GetReaderLock()
        {
            this._RWLockRules.AcquireReaderLock(-1);
        }

        private void GetWriterLock()
        {
            this._RWLockRules.AcquireWriterLock(-1);
        }

        private static bool HandleMatch(Session oSession, ResponderRule oMatch)
        {
            setStringDelegate oDel = null;
            setStringDelegate delegate3 = null;
            bool flag = oSession.HTTPMethodIs("CONNECT");
            if (oMatch.sAction.StartsWith("*"))
            {
                if (oMatch.sAction.Equals("*drop", StringComparison.OrdinalIgnoreCase))
                {
                    DoDelay(oMatch);
                    if ((oSession.oRequest != null) && (oSession.oRequest.pipeClient != null))
                    {
                        oSession.oRequest.pipeClient.End();
                    }
                    oSession.utilCreateResponseAndBypassServer();
                    oSession.oResponse.headers.HTTPResponseCode = 0;
                    oSession.oResponse.headers.HTTPResponseStatus = "0 Client Connection Dropped";
                    oSession["ui-backcolor"] = "Lavender";
                    oSession.state = SessionStates.Aborted;
                    return true;
                }
                if (oMatch.sAction.Equals("*reset", StringComparison.OrdinalIgnoreCase))
                {
                    DoDelay(oMatch);
                    if ((oSession.oRequest != null) && (oSession.oRequest.pipeClient != null))
                    {
                        oSession.oRequest.pipeClient.EndWithRST();
                    }
                    oSession.utilCreateResponseAndBypassServer();
                    oSession.oResponse.headers.HTTPResponseCode = 0;
                    oSession.oResponse.headers.HTTPResponseStatus = "0 Client Connection Reset";
                    oSession["ui-backcolor"] = "Lavender";
                    oSession.state = SessionStates.Aborted;
                    return true;
                }
                if (oMatch.sAction.StartsWith("*ReplyWithTunnel", StringComparison.OrdinalIgnoreCase))
                {
                    DoDelay(oMatch);
                    oSession["X-ReplyWithTunnel"] = "*Reply rule";
                    return true;
                }
                if (oMatch.sAction.StartsWith("*CORSPreflightAllow", StringComparison.OrdinalIgnoreCase))
                {
                    DoDelay(oMatch);
                    oSession.utilCreateResponseAndBypassServer();
                    oSession.oResponse.headers.HTTPResponseCode = 200;
                    oSession.oResponse.headers.HTTPResponseStatus = "200 Fiddler CORSPreflightAllow";
                    string str = oSession.oRequest["Origin"];
                    if (string.IsNullOrEmpty(str))
                    {
                        str = "*";
                    }
                    oSession.oResponse["Access-Control-Allow-Origin"] = str;
                    string str2 = oSession.oRequest["Access-Control-Request-Method"];
                    if (!string.IsNullOrEmpty(str2))
                    {
                        oSession.oResponse["Access-Control-Allow-Methods"] = str2;
                    }
                    string str3 = oSession.oRequest["Access-Control-Request-Headers"];
                    if (!string.IsNullOrEmpty(str3))
                    {
                        oSession.oResponse["Access-Control-Allow-Headers"] = str3;
                    }
                    oSession.oResponse["Access-Control-Max-Age"] = "1";
                    oSession.oResponse["Access-Control-Allow-Credentials"] = "true";
                    oSession["ui-backcolor"] = "Lavender";
                    oSession.state = SessionStates.Aborted;
                    return true;
                }
                if (oMatch.sAction.StartsWith("*delay:", StringComparison.OrdinalIgnoreCase))
                {
                    int result = 0;
                    if (int.TryParse(Utilities.TrimBefore(oMatch.sAction, ':'), out result))
                    {
                        Thread.Sleep(result);
                    }
                    return false;
                }
                if (oMatch.sAction.StartsWith("*flag:", StringComparison.OrdinalIgnoreCase))
                {
                    string key = Utilities.TrimAfter(oMatch.sAction.Substring(6), "=");
                    string str5 = Utilities.TrimBefore(oMatch.sAction, "=");
                    if (str5.Length > 0)
                    {
                        oSession.oFlags[key] = str5;
                    }
                    else
                    {
                        oSession.oFlags.Remove(key);
                    }
                    return false;
                }
                if (oMatch.sAction.StartsWith("*header:", StringComparison.OrdinalIgnoreCase))
                {
                    string sHeaderName = Utilities.TrimAfter(oMatch.sAction.Substring(8), "=");
                    string str7 = Utilities.TrimBefore(oMatch.sAction, "=");
                    if (str7.Length > 0)
                    {
                        oSession.oRequest[sHeaderName] = str7;
                    }
                    else
                    {
                        oSession.oRequest.headers.Remove(sHeaderName);
                    }
                    return false;
                }
                if (oMatch.sAction.Equals("*bpafter", StringComparison.OrdinalIgnoreCase))
                {
                    oSession["x-breakresponse"] = "AutoResponder";
                    oSession.bBufferResponse = true;
                    return false;
                }
                if (oMatch.sAction.StartsWith("*redir:", StringComparison.OrdinalIgnoreCase) && !flag)
                {
                    DoDelay(oMatch);
                    oSession.utilCreateResponseAndBypassServer();
                    oSession.oResponse.headers.HTTPResponseCode = 0x133;
                    oSession.oResponse.headers.HTTPResponseStatus = "307 AutoRedir";
                    if (oDel == null)
                    {
                        oDel = delegate(string sReplaceWith)
                        {
                            oSession.oResponse.headers["Location"] = sReplaceWith.Substring(7);
                        };
                    }
                    if (!IfRuleIsRegExCallReplacementFunction(oMatch, oSession.fullUrl, oDel))
                    {
                        oSession.oResponse.headers["Location"] = oMatch.sAction.Substring(7);
                    }
                    oSession.oResponse.headers["Cache-Control"] = "max-age=0, must-revalidate";
                    oSession["ui-backcolor"] = "Lavender";
                    return true;
                }
                if (oMatch.sAction.Equals("*exit", StringComparison.OrdinalIgnoreCase))
                {
                    DoDelay(oMatch);
                    return true;
                }
            }
            if (oMatch.HasImportedResponse)
            {
                if (flag)
                {
                    return false;
                }
                if (oSession.state < SessionStates.SendingRequest)
                {
                    oSession.utilCreateResponseAndBypassServer();
                    oSession["ui-backcolor"] = "Lavender";
                }
                else
                {
                    FiddlerApplication.Log.LogFormat("fiddler.autoresponder.error> AutoResponder will not respond to a request which is already in-flight; Session #{0} is at state: {1}", new object[] { oSession.id, oSession.state });
                    return true;
                }
                if ((oMatch._arrResponseBodyBytes == null) || (oMatch._oResponseHeaders == null))
                {
                    FiddlerApplication.Log.LogString("fiddler.autoresponder.error> Response data from imported session is missing.");
                    return true;
                }
                DoDelay(oMatch);
                if (oSession.HTTPMethodIs("HEAD"))
                {
                    oSession.responseBodyBytes = new byte[0];
                }
                else
                {
                    oSession.responseBodyBytes = oMatch._arrResponseBodyBytes;
                }
                oSession.oResponse.headers = (HTTPResponseHeaders)oMatch._oResponseHeaders.Clone();
                oSession.state = SessionStates.AutoTamperResponseBefore;
                oSession["x-AutoResponder"] = "Matched: " + oMatch.sMatch + ", sent: " + oMatch.sAction;
                return true;
            }
            if (!flag && ((oMatch.sAction.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || oMatch.sAction.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) || oMatch.sAction.StartsWith("ftp://", StringComparison.OrdinalIgnoreCase)))
            {
                DoDelay(oMatch);
                oSession.oFlags["X-OriginalURL"] = oSession.fullUrl;
                oSession["ui-backcolor"] = "Lavender";
                if (delegate3 == null)
                {
                    delegate3 = delegate(string sReplaceWith)
                    {
                        oSession.fullUrl = sReplaceWith;
                    };
                }
                if (!IfRuleIsRegExCallReplacementFunction(oMatch, oSession.fullUrl, delegate3))
                {
                    oSession.fullUrl = oMatch.sAction;
                }
                return true;
            }
            DoDelay(oMatch);
            if (!IfRuleIsRegExCallReplacementFunction(oMatch, oSession.fullUrl, delegate(string sReplaceWith)
            {
                if ((sReplaceWith.StartsWith("http://") || sReplaceWith.StartsWith("https://")) || sReplaceWith.StartsWith("ftp://"))
                {
                    oSession.oFlags["X-OriginalURL"] = oSession.fullUrl;
                    oSession.fullUrl = sReplaceWith;
                }
                else
                {
                    oSession["x-replywithfile"] = sReplaceWith.Replace('/', '\\');
                }
            }))
            {
                oSession["x-replywithfile"] = oMatch.sAction;
            }
            oSession["ui-backcolor"] = "Lavender";
            return true;
        }

        private static bool IfRuleIsRegExCallReplacementFunction(ResponderRule oMatch, string sInURI, setStringDelegate oDel)
        {
            string str2;
            string sMatch = oMatch.sMatch;
            if (sMatch.StartsWith("METHOD:", StringComparison.OrdinalIgnoreCase))
            {
                sMatch = Utilities.TrimBefore(sMatch.Substring(7), ' ');
            }
            if (sMatch.Length >= 7)
            {
                if (sMatch.StartsWith("REGEX:", StringComparison.OrdinalIgnoreCase))
                {
                    str2 = sMatch.Substring(6);
                    goto Label_0069;
                }
                if (sMatch.StartsWith("URLWithBody:REGEX:", StringComparison.OrdinalIgnoreCase))
                {
                    str2 = Utilities.TrimAfter(sMatch.Substring(0x12), ' ');
                    goto Label_0069;
                }
            }
            return false;
        Label_0069:
            if (str2 == ".*")
            {
                str2 = "^.+$";
            }
            try
            {
                string sNew = new Regex(str2).Replace(sInURI, oMatch.sAction);
                oDel(sNew);
            }
            catch
            {
                return false;
            }
            return true;
        }

        internal bool ImportFARX(string sFilename)
        {
            return this.LoadRules(sFilename, false);
        }

        public bool ImportSAZ(string sFilename)
        {
            return this.ImportSAZ(sFilename, false);
        }

        public bool ImportSAZ(string sFilename, bool bUsePlaybackHeuristics)
        {
            Session[] oSessions = Utilities.ReadSessionArchive(sFilename, true);
            if (oSessions == null)
            {
                return false;
            }
            if (sFilename.StartsWith(CONFIG.GetPath("Captures"), StringComparison.OrdinalIgnoreCase))
            {
                sFilename = sFilename.Substring(CONFIG.GetPath("Captures").Length);
            }
            else
            {
                sFilename = Utilities.CollapsePath(sFilename);
            }
            return this.ImportSessions(oSessions, sFilename, bUsePlaybackHeuristics);
        }

        public bool ImportSessions(Session[] oSessions)
        {
            return this.ImportSessions(oSessions, null, false);
        }

        private bool ImportSessions(Session[] oSessions, string sAnnotation, bool bUsePlaybackHeuristics)
        {
            if ((oSessions == null) || (oSessions.Length < 1))
            {
                return false;
            }
            foreach (Session session in oSessions)
            {
                if (session.HTTPMethodIs("CONNECT"))
                {
                    if (bUsePlaybackHeuristics && (200 == session.responseCode))
                    {
                        string sRule = "METHOD:CONNECT " + session.fullUrl;
                        if (this._alRules.Find(delegate(ResponderRule oCandidateRule)
                        {
                            return oCandidateRule.sMatch == sRule;
                        }) == null)
                        {
                            this.AddRule(sRule, "*ReplyWithTunnel", true);
                        }
                    }
                }
                else if ((session.bHasResponse && (session.oResponse != null)) && (!bUsePlaybackHeuristics || (0x191 != session.responseCode)))
                {
                    string str;
                    if (((bUsePlaybackHeuristics && session.HTTPMethodIs("POST")) && ((session.oRequest != null) && (session.oRequest.headers != null))) && session.oRequest.headers.Exists("SOAPAction"))
                    {
                        str = "Header:SOAPAction=" + session.oRequest.headers["SOAPAction"];
                    }
                    else
                    {
                        str = "EXACT:" + session.fullUrl;
                    }
                    string sDescription = string.Format("*{0}-{1}", session.responseCode, (sAnnotation == null) ? ("SESSION_" + session.id.ToString()) : (sAnnotation + "#" + session.oFlags["x-LoadedFrom"]));
                    int iLatencyMS = 0;
                    if (session.Timers != null)
                    {
                        TimeSpan span = (TimeSpan)(session.Timers.ServerBeginResponse - session.Timers.ClientDoneRequest);
                        iLatencyMS = (int)span.TotalMilliseconds;
                    }
                    byte[] arrResponseBody = Utilities.Dupe(session.responseBodyBytes);
                    HTTPResponseHeaders oRH = (HTTPResponseHeaders)session.oResponse.headers.Clone();
                    if (bUsePlaybackHeuristics)
                    {
                        foreach (ResponderRule rule in this._alRules)
                        {
                            if (rule.sMatch == str)
                            {
                                rule.bDisableOnMatch = true;
                            }
                        }
                    }
                    this.AddRule(str, oRH, arrResponseBody, sDescription, iLatencyMS, true);
                }
            }
            this._bRuleListIsDirty = true;
            return true;
        }

        private static bool IsBodyMatch(Session oSession, string sBodyToMatch)
        {
            if ((oSession == null) || string.IsNullOrEmpty(sBodyToMatch))
            {
                return true;
            }
            try
            {
                string requestBodyAsString = oSession.GetRequestBodyAsString();
                if (string.IsNullOrEmpty(requestBodyAsString))
                {
                    return false;
                }
                if ((sBodyToMatch.Length > 6) && sBodyToMatch.StartsWith("REGEX:", StringComparison.OrdinalIgnoreCase))
                {
                    string pattern = sBodyToMatch.Substring(6);
                    try
                    {
                        Regex regex = new Regex(pattern);
                        if (regex.Match(requestBodyAsString).Success)
                        {
                            return true;
                        }
                    }
                    catch
                    {
                    }
                    return false;
                }
                if ((sBodyToMatch.Length > 6) && sBodyToMatch.StartsWith("EXACT:", StringComparison.OrdinalIgnoreCase))
                {
                    return sBodyToMatch.Substring(6).Equals(requestBodyAsString, StringComparison.Ordinal);
                }
                if ((sBodyToMatch.Length > 4) && sBodyToMatch.StartsWith("NOT:", StringComparison.OrdinalIgnoreCase))
                {
                    string str4 = sBodyToMatch.Substring(4);
                    return (requestBodyAsString.IndexOf(str4, StringComparison.OrdinalIgnoreCase) < 0);
                }
                if (-1 < requestBodyAsString.IndexOf(sBodyToMatch, StringComparison.OrdinalIgnoreCase))
                {
                    return true;
                }
            }
            catch
            {
                return false;
            }
            return false;
        }

        internal void LoadRules()
        {
            this.LoadRules(CONFIG.GetPath("AutoResponderDefaultRules"), true);
        }

        public bool LoadRules(string sFilename)
        {
            return this.LoadRules(sFilename, true);
        }

        public bool LoadRules(string sFilename, bool bIsDefaultRuleFile)
        {
            if (bIsDefaultRuleFile)
            {
                this.ClearRules();
            }
            try
            {
                if (!File.Exists(sFilename) || (new FileInfo(sFilename).Length < 0x8fL))
                {
                    return false;
                }
                FileStream input = new FileStream(sFilename, FileMode.Open, FileAccess.Read, FileShare.Read);
                using (input)
                {
                    XmlTextReader reader = new XmlTextReader(input);
                    while (reader.Read())
                    {
                        string str6;
                        if ((reader.NodeType == XmlNodeType.Element) && ((str6 = reader.Name) != null))
                        {
                            if (!(str6 == "State"))
                            {
                                if (str6 == "ResponseRule")
                                {
                                    goto Label_00E3;
                                }
                            }
                            else if (bIsDefaultRuleFile)
                            {
                                this.IsEnabled = "true" == reader.GetAttribute("Enabled");
                                this.PermitFallthrough = !("false" == reader.GetAttribute("Fallthrough"));
                                this.UseLatency = "true" == reader.GetAttribute("UseLatency");
                            }
                        }
                        continue;
                    Label_00E3:
                        try
                        {
                            string attribute = reader.GetAttribute("Match");
                            string sAction = reader.GetAttribute("Action");
                            int iLatencyMS = 0;
                            string s = reader.GetAttribute("Latency");
                            if (s != null)
                            {
                                iLatencyMS = XmlConvert.ToInt32(s);
                            }
                            bool bIsEnabled = "false" != reader.GetAttribute("Enabled");
                            string str4 = reader.GetAttribute("Headers");
                            if (string.IsNullOrEmpty(str4))
                            {
                                this.AddRule(attribute, sAction, bIsEnabled);
                            }
                            else
                            {
                                byte[] buffer;
                                HTTPResponseHeaders oRH = new HTTPResponseHeaders();
                                str4 = Encoding.UTF8.GetString(Convert.FromBase64String(str4));
                                oRH.AssignFromString(str4);
                                string str5 = reader.GetAttribute("DeflatedBody");
                                if (!string.IsNullOrEmpty(str5))
                                {
                                    buffer = Utilities.DeflaterExpand(Convert.FromBase64String(str5));
                                }
                                else
                                {
                                    str5 = reader.GetAttribute("Body");
                                    if (!string.IsNullOrEmpty(str5))
                                    {
                                        buffer = Convert.FromBase64String(str5);
                                    }
                                    else
                                    {
                                        buffer = new byte[0];
                                    }
                                }
                                this.AddRule(attribute, oRH, buffer, sAction, iLatencyMS, bIsEnabled);
                            }
                            continue;
                        }
                        catch
                        {
                            continue;
                        }
                    }
                }
                if (bIsDefaultRuleFile && (this._alRules.Count < 1))
                {
                    this.IsEnabled = false;
                }
                if (bIsDefaultRuleFile)
                {
                    this._bRuleListIsDirty = false;
                }
                return true;
            }
            catch (Exception exception)
            {
                FiddlerApplication.ReportException(exception, "Failed to load AutoResponder settings from " + sFilename);
                if (bIsDefaultRuleFile)
                {
                    this.IsEnabled = false;
                }
                return false;
            }
        }

        internal bool PromoteRule(ResponderRule oRule)
        {
            bool flag;
            try
            {
                this.GetWriterLock();
                int index = this._alRules.IndexOf(oRule);
                if (index > 0)
                {
                    this._alRules.Reverse(index - 1, 2);
                    this._bRuleListIsDirty = true;
                    return true;
                }
                flag = false;
            }
            finally
            {
                this.FreeWriterLock();
            }
            return flag;
        }

        public bool RemoveRule(ResponderRule oRule)
        {
            try
            {
                try
                {
                    this.GetWriterLock();
                    this._alRules.Remove(oRule);
                }
                finally
                {
                    this.FreeWriterLock();
                }
                this._bRuleListIsDirty = true;
                if (oRule.ViewItem != null)
                {
                    oRule.ViewItem.Remove();
                    oRule.ViewItem = null;
                }
                if (oRule._oEditor != null)
                {
                    oRule._oEditor.Dispose();
                    oRule._oEditor = null;
                }
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        internal void SaveDefaultRules()
        {
            if (this._bRuleListIsDirty)
            {
                this.SaveRules(CONFIG.GetPath("AutoResponderDefaultRules"));
                this._bRuleListIsDirty = false;
            }
        }

        public bool SaveRules(string sFilename)
        {
            try
            {
                Utilities.EnsureOverwritable(sFilename);
                XmlTextWriter writer = new XmlTextWriter(sFilename, Encoding.UTF8);
                writer.Formatting = Formatting.Indented;
                writer.WriteStartDocument();
                writer.WriteStartElement("AutoResponder");
                writer.WriteAttributeString("LastSave", XmlConvert.ToString(DateTime.Now, XmlDateTimeSerializationMode.RoundtripKind));
                writer.WriteAttributeString("FiddlerVersion", Application.ProductVersion);
                writer.WriteStartElement("State");
                writer.WriteAttributeString("Enabled", XmlConvert.ToString(this._bEnabled));
                writer.WriteAttributeString("Fallthrough", XmlConvert.ToString(this._bPermitFallthrough));
                writer.WriteAttributeString("UseLatency", XmlConvert.ToString(this._bUseLatency));
                try
                {
                    this.GetReaderLock();
                    foreach (ResponderRule rule in this._alRules)
                    {
                        writer.WriteStartElement("ResponseRule");
                        writer.WriteAttributeString("Match", rule.sMatch);
                        writer.WriteAttributeString("Action", rule.sAction);
                        if (rule.iLatency > 0)
                        {
                            writer.WriteAttributeString("Latency", rule.iLatency.ToString());
                        }
                        writer.WriteAttributeString("Enabled", XmlConvert.ToString(rule.IsEnabled));
                        if (rule.HasImportedResponse)
                        {
                            byte[] buffer = rule._oResponseHeaders.ToByteArray(true, true);
                            writer.WriteStartAttribute("Headers");
                            writer.WriteBase64(buffer, 0, buffer.Length);
                            writer.WriteEndAttribute();
                            byte[] writeData = rule._arrResponseBodyBytes;
                            if ((writeData != null) && (writeData.Length > 0))
                            {
                                if (writeData.Length > 0x800)
                                {
                                    byte[] buffer3 = Utilities.DeflaterCompress(writeData);
                                    if (buffer3.Length < (0.9 * writeData.Length))
                                    {
                                        writer.WriteStartAttribute("DeflatedBody");
                                        writer.WriteBase64(buffer3, 0, buffer3.Length);
                                        writer.WriteEndAttribute();
                                        writeData = null;
                                    }
                                }
                                if (writeData != null)
                                {
                                    writer.WriteStartAttribute("Body");
                                    writer.WriteBase64(writeData, 0, writeData.Length);
                                    writer.WriteEndAttribute();
                                }
                            }
                        }
                        writer.WriteEndElement();
                    }
                }
                finally
                {
                    this.FreeReaderLock();
                }
                writer.WriteEndElement();
                writer.WriteEndElement();
                writer.WriteEndDocument();
                writer.Close();
                return true;
            }
            catch (Exception exception)
            {
                FiddlerApplication.ReportException(exception, "Failed to save AutoResponder Rules");
                return false;
            }
        }

        public override string ToString()
        {
            StringBuilder builder = new StringBuilder();
            try
            {
                this.GetReaderLock();
                builder.AppendFormat("The AutoResponder list contains {0} rules.\r\n", this._alRules.Count);
                foreach (ResponderRule rule in this._alRules)
                {
                    builder.AppendFormat("\t{0}\t->\t{1}\r\n", rule.sMatch, rule.sAction);
                }
            }
            finally
            {
                this.FreeReaderLock();
            }
            return builder.ToString();
        }

        public bool IsEnabled
        {
            get
            {
                return this._bEnabled;
            }
            set
            {
                if (value != this._bEnabled)
                {
                    FiddlerApplication.UIInvoke(delegate
                    {
                        this.oAutoResponderUI.cbAutoRespond.Checked = this._bEnabled = value;
                    });
                    this._bRuleListIsDirty = true;
                }
            }
        }

        public bool IsRuleListDirty
        {
            get
            {
                return this._bRuleListIsDirty;
            }
            set
            {
                this._bRuleListIsDirty = value;
            }
        }

        public bool PermitFallthrough
        {
            get
            {
                return this._bPermitFallthrough;
            }
            set
            {
                if (value != this._bPermitFallthrough)
                {
                    FiddlerApplication.UIInvoke(delegate
                    {
                        this.oAutoResponderUI.cbRespondPassthrough.Checked = this._bPermitFallthrough = value;
                    });
                    this._bRuleListIsDirty = true;
                }
            }
        }

        public bool UseLatency
        {
            get
            {
                return this._bUseLatency;
            }
            set
            {
                if (value != this._bUseLatency)
                {
                    FiddlerApplication.UIInvoke(delegate
                    {
                        this.oAutoResponderUI.cbRespondUseLatency.Checked = this._bUseLatency = value;
                        this.oAutoResponderUI.lvRespondRules.Columns[2].Width = value ? 60 : 0;
                    });
                    this._bRuleListIsDirty = true;
                }
            }
        }
    }
}

